package org.anddev.andengine.extension.svg.node;
/**
 * @author Eric Depta
 * @since 01:14:00 - 28.02.2011
 */
import java.util.List;

import org.anddev.andengine.entity.shape.Shape;
import org.anddev.andengine.extension.svg.SVGDoc;
import org.anddev.andengine.extension.svg.SVGPath;
import org.anddev.andengine.extension.svg.util.physic.ExtendedPhysicsFactory;
import org.anddev.andengine.extension.svg.util.render.Render;
import org.anddev.andengine.extension.svg.util.render.TriangleShape;
import org.anddev.andengine.extension.svg.util.transform.TransformDoc;
import org.anddev.andengine.util.MathUtils;
import org.anddev.andengine.util.SAXUtils;
import org.xml.sax.Attributes;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;

public class PathNode extends DrawablePhysicNode {
	protected SVGPath svgPath = null;
	
	public PathNode(final SVGDoc pSVGDoc){
		super(pSVGDoc);
	}
	
	public void create(final Attributes pAttributes, final TransformDoc pTransform){
		super.create(pAttributes, pTransform);
	}
	
	@Override
	protected Body createPhysics(Shape pShape, Attributes pAttributes) {
		if(pShape == null || !this.svgPath.isValid()) return null;
		Body body = null;
		
		if(super.isHasPhysic() && super.mSVGDoc.mPhysicsWorld != null){
			
			if(this.svgPath.isClosed()){
				body = ExtendedPhysicsFactory.createTrianglulatedBody(
					super.mSVGDoc.mPhysicsWorld, 
					pShape,
					this.svgPath.getPhysicVerticesTriangleList(super.mTransformation),
					BodyType.values()[SAXUtils.getIntAttribute(pAttributes, TAG_ATTRIBUTE_BODYTYPE, 0)], 
					super.createFixtureDef(pAttributes)
				);
			}else{
				body = ExtendedPhysicsFactory.createLinesBody(
					super.mSVGDoc.mPhysicsWorld, 
					pShape,
					this.svgPath.getPhysicVertices(super.mTransformation), 
					BodyType.values()[SAXUtils.getIntAttribute(pAttributes, TAG_ATTRIBUTE_BODYTYPE, 0)], 
					super.createFixtureDef(pAttributes)
				);
			}
			super.setBodyOptions(pAttributes, body);
			
			//-- Init Rotation  
			body.setTransform(
				body.getWorldCenter(),
				MathUtils.degToRad(pShape.getRotation())
			);
			
			super.registerPhysicsConnector(pAttributes, pShape, body);
		}else if(super.isHasDrawables()){
			//-- Velocitys to shape
			super.createPhysicHandler(pAttributes,pShape);
		}
		
		return body;
	}
	
	protected void createPath(final Attributes pAttributes){
		this.svgPath = new SVGPath(
			SAXUtils.getAttributeOrThrow(pAttributes, TAG_ATTRIBUTE_PATH),
			SAXUtils.getIntAttribute(pAttributes, TAG_ATTRIBUTE_CURVE_SEGMENTS, 4)
		);
	}
	
	@Override
	protected Shape createShape(final Attributes pAttributes) {
		this.createPath(pAttributes);
		
		if(this.svgPath.isValid()){
			final String source = SAXUtils.getAttribute(pAttributes, TAG_ATTRIBUTE_SPRITESRC, "");
			Shape shape = null;
			if(source != "" && !super.mSVGDoc.getDebug() && super.mSVGDoc.mTextureManager != null){
				//-- Sprite
				shape = super.createSprite(
					pAttributes, 
					source,
					this.svgPath.getAABB().getX(),
					this.svgPath.getAABB().getY(),
					this.svgPath.getAABB().getWidth(),
					this.svgPath.getAABB().getHeight(),
					this.svgPath.getAABB().getRotation(),
					this.svgPath.getAABB().getScaleX(),
					this.svgPath.getAABB().getScaleY()
				);
				super.setHasSprite(true);
			}else if(super.isHasPhysic() || super.isHasDrawables()){
				//-- Boundings
				shape = this.svgPath.getAABB();
				shape.setAlpha(0);
			}
			
			this.mTransformation.transformShape(shape);
			
			this.drawPrimitives(pAttributes, shape);
			
			return shape;
		}
		return null;
	}
	
	@Override
	protected void drawPrimitivesFill(final Shape pShape, final float[] pColor, final float pAlpha){
		if(this.svgPath.isClosed()){
			final List<Vector2> vecs = this.svgPath.getVerticesTriangleList();
			float[] triangle = new float[6];
			for(int i=0;i<vecs.size();i+=3){
				triangle[0] = vecs.get(i).x;
				triangle[1] = vecs.get(i).y;
				triangle[2] = vecs.get(i+1).x;
				triangle[3] = vecs.get(i+1).y;
				triangle[4] = vecs.get(i+2).x;
				triangle[5] = vecs.get(i+2).y;
				final TriangleShape tri = new TriangleShape(0, 0, triangle);
				tri.setColor(
					pColor[0], 
					pColor[1], 
					pColor[2], 
					pAlpha
				);
				pShape.attachChild(tri);
			}
		}
	}
	
	@Override
	protected void drawPrimitivesLine(final Shape pShape, final float[] pColor, final float pAlpha, final float pWidth, final boolean pAntiAlias){
		Render.lineRenderRel(
			this.svgPath.getVertices(), 
			pShape, 
			pColor, 
			pAlpha, 
			pWidth,
			pAntiAlias,
			this.svgPath.isClosed()
		);
	}
	
}
